<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chemical Bonds Test</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background: #1a1a1a;
        }

        canvas {
            display: block;
        }
    </style>
</head>

<body>
    <script>
        // 原子半径（范德华半径，单位：Å）
        const atomRadii = {
            'H': 1.20,
            'C': 1.70,
            'O': 1.52,
            'default': 1.80
        };

        // 原子颜色映射
        const atomColors = {
            'H': 0xFFFFFF,  // 白色
            'C': 0x909090,  // 灰色
            'O': 0xFF0D0D,  // 红色
            'default': 0xFF69B4 // 粉色（默认）
        };

        // 初始化Three.js
        const scene = new THREE.Scene();
        scene.background = new THREE.Color(0x0a0a0a);

        const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.z = 15;

        const renderer = new THREE.WebGLRenderer({ antialias: true });
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 添加灯光
        const ambientLight = new THREE.AmbientLight(0x404040, 0.6);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
        directionalLight.position.set(1, 1, 1);
        scene.add(directionalLight);

        const pointLight = new THREE.PointLight(0xffffff, 0.5);
        pointLight.position.set(5, 5, 5);
        scene.add(pointLight);

        // 创建测试分子（水分子 H2O）
        const atoms = [
            { element: 'O', x: 0, y: 0, z: 0 },
            { element: 'H', x: 0.96, y: 0, z: 0 },
            { element: 'H', x: -0.24, y: 0.93, z: 0 }
        ];

        const bondDistanceThreshold = 2.0;
        const bondRadius = 0.1;

        // 创建原子（棍球模式，半径减半）
        atoms.forEach(atom => {
            const color = atomColors[atom.element] || atomColors['default'];
            const radius = (atomRadii[atom.element] || atomRadii['default']) * 0.5;

            const geometry = new THREE.SphereGeometry(radius, 16, 16);
            const material = new THREE.MeshPhongMaterial({ color });
            const sphere = new THREE.Mesh(geometry, material);

            sphere.position.set(atom.x, atom.y, atom.z);
            scene.add(sphere);

            console.log(`Atom ${atom.element} at (${atom.x}, ${atom.y}, ${atom.z}) with radius ${radius}`);
        });

        // 创建化学键
        for (let i = 0; i < atoms.length; i++) {
            for (let j = i + 1; j < atoms.length; j++) {
                const atom1 = atoms[i];
                const atom2 = atoms[j];

                const x1 = atom1.x, y1 = atom1.y, z1 = atom1.z;
                const x2 = atom2.x, y2 = atom2.y, z2 = atom2.z;

                const distance = Math.sqrt(
                    Math.pow(x2 - x1, 2) +
                    Math.pow(y2 - y1, 2) +
                    Math.pow(z2 - z1, 2)
                );

                console.log(`Distance between ${atom1.element} and ${atom2.element}: ${distance.toFixed(2)} Å`);

                if (distance < bondDistanceThreshold) {
                    const direction = new THREE.Vector3().subVectors(
                        new THREE.Vector3(x2, y2, z2),
                        new THREE.Vector3(x1, y1, z1)
                    );
                    const orientation = new THREE.Matrix4();
                    orientation.lookAt(new THREE.Vector3(0, 0, 0), direction, new THREE.Vector3(0, 1, 0));

                    // 获取原子半径来计算化学键的起始和结束位置
                    const radius1 = (atomRadii[atom1.element] || atomRadii['default']) * 0.5;
                    const radius2 = (atomRadii[atom2.element] || atomRadii['default']) * 0.5;

                    // 计算化学键的实际长度（减去两个原子的半径）
                    const actualBondLength = Math.max(0.1, distance - radius1 - radius2);

                    const cylinderGeometry = new THREE.CylinderGeometry(
                        bondRadius,
                        bondRadius,
                        actualBondLength,
                        8
                    );
                    cylinderGeometry.applyMatrix4(orientation);

                    const cylinderMaterial = new THREE.MeshPhongMaterial({
                        color: 0xCCCCCC // 键的颜色为灰色
                    });
                    const cylinder = new THREE.Mesh(cylinderGeometry, cylinderMaterial);

                    // 计算化学键的起始位置（第一个原子球心向外延伸半径距离）
                    const normalizedDirection = direction.clone().normalize();
                    const startPosition = new THREE.Vector3(x1, y1, z1)
                        .add(normalizedDirection.clone().multiplyScalar(radius1));

                    // 计算化学键的结束位置（第二个原子球心向内延伸半径距离）
                    const endPosition = new THREE.Vector3(x2, y2, z2)
                        .sub(normalizedDirection.clone().multiplyScalar(radius2));

                    // 将圆柱体放置在化学键的中间位置
                    cylinder.position.set(
                        (startPosition.x + endPosition.x) / 2,
                        (startPosition.y + endPosition.y) / 2,
                        (startPosition.z + endPosition.z) / 2
                    );

                    scene.add(cylinder);

                    console.log(`Bond created between ${atom1.element} and ${atom2.element}`);
                    console.log(`  - Atom radii: ${radius1.toFixed(2)} and ${radius2.toFixed(2)}`);
                    console.log(`  - Bond length: ${actualBondLength.toFixed(2)}`);
                    console.log(`  - Start position: (${startPosition.x.toFixed(2)}, ${startPosition.y.toFixed(2)}, ${startPosition.z.toFixed(2)})`);
                    console.log(`  - End position: (${endPosition.x.toFixed(2)}, ${endPosition.y.toFixed(2)}, ${endPosition.z.toFixed(2)})`);
                    console.log(`  - Bond center: (${cylinder.position.x.toFixed(2)}, ${cylinder.position.y.toFixed(2)}, ${cylinder.position.z.toFixed(2)})`);
                }
            }
        }

        // 动画循环
        function animate() {
            requestAnimationFrame(animate);
            renderer.render(scene, camera);
        }
        animate();

        // 窗口调整大小
        window.addEventListener('resize', () => {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        });
    </script>
</body>

</html>